package cn.ubeta.ar.camera;

/**
 * Created by fengyijun on 2016/12/19.
 */

import android.content.Context;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.view.SurfaceHolder;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import cn.ubeta.ar.utils.DisplayUtil;

import static android.R.attr.y;

public class CameraInterface {

    private Camera mCamera;
    private Camera.Parameters mParams;
    private boolean isPreviewing = false;
    private int mCameraId = -1;
    private static CameraInterface mCameraInterface;

    public interface CamOpenOverCallback {
        void cameraHasOpened();
    }

    public static synchronized CameraInterface getInstance() {
        if (mCameraInterface == null) {
            mCameraInterface = new CameraInterface();
        }
        return mCameraInterface;
    }

    public void doOpenCamera(CamOpenOverCallback callback, int cameraId) {
        mCamera = Camera.open(cameraId);
        mCameraId = cameraId;
        mCamera.setPreviewCallbackWithBuffer(null);
        if (callback != null) {
            callback.cameraHasOpened();
        }
    }

    public void doStartPreview(Context context, SurfaceHolder holder) {
        if (isPreviewing) {
            mCamera.stopPreview();
            return;
        }
        if (mCamera != null) {
            mParams = mCamera.getParameters();
            //CamParaUtil.getInstance().printSupportPreviewSize(mParams);

            // sort
            List<Size> list = mParams.getSupportedPreviewSizes();
            Collections.sort(list, new Comparator<Size>() {
                @Override
                public int compare(Size lhs, Size rhs) {
                    return lhs.width * lhs.height - rhs.width * rhs.height;
                }
            });

            final float ratioScreen = (float)DisplayUtil.getScreenHeight(context) / (float)DisplayUtil.getScreenWidth(context);

            // find best preview size
            float min = 1F;
            Size bestSize = null;
            for (Size size : list) {
                float ratio = (float)size.width / (float)size.height;
                // find the best size
                if (Math.abs(ratioScreen - ratio) < min) {
                    min = Math.abs(ratioScreen - ratio);
                    bestSize = size;
                }
            }

            //Size previewSize = CamParaUtil.getInstance().getPropPreviewSize(mParams.getSupportedPreviewSizes(), previewRate, mParams.getPreferredPreviewSizeForVideo());
            mParams.setPreviewSize(bestSize.width, bestSize.height);
            mParams.setRecordingHint(true);
            mCamera.setDisplayOrientation(90);

            CamParaUtil.getInstance().printSupportFocusMode(mParams);
            List<String> focusModes = mParams.getSupportedFocusModes();
            if (focusModes.contains("continuous-video")) {
                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }
            mCamera.setParameters(mParams);
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
            isPreviewing = true;

            mParams = mCamera.getParameters();
        }
    }

    public void doStopCamera() {
        if (null != mCamera) {
            mCamera.setPreviewCallbackWithBuffer(null);
            mCamera.stopPreview();
            isPreviewing = false;
            mCamera.release();
            mCamera = null;
        }
    }

    public Camera.Parameters getCameraParams() {
        if (mCamera != null) {
            mParams = mCamera.getParameters();
            return mParams;
        }
        return null;
    }

    public Camera getCameraDevice() {
        return mCamera;
    }

    public int getCameraId() {
        return mCameraId;
    }
}
